/**
 * @file gameserverwidget.cpp
 * @brief 游戏服务器界面组件实现文件
 *
 * 实现游戏服务器管理界面的所有功能，包括：
 * - UI组件的创建和布局管理
 * - 服务器数据的显示和格式化
 * - 用户交互事件的处理
 * - 字符串格式化和数据转换
 * - 样式应用和主题管理
 */

#include "../include/gameserverwidget.h"
#include "../include/config.h"
#include <QMessageBox>      // 消息框组件
#include <QDesktopServices> // 桌面服务
#include <QUrl>             // URL处理
#include <QDateTime>        // 日期时间处理
// #include <QRandomGenerator> // 已删除：不再使用伪造数据

/**
 * @brief GameServerWidget构造函数
 * @param gameService 游戏服务指针
 * @param authService 认证服务指针
 * @param parent 父窗口指针
 *
 * 初始化游戏服务器界面的所有组件：
 * 1. 设置颜色主题和样式配置
 * 2. 创建UI布局和组件
 * 3. 建立信号槽连接
 * 4. 启动自动刷新定时器
 * 5. 执行初始数据加载
 */
GameServerWidget::GameServerWidget(GameService *gameService, AuthService *authService, QWidget *parent)
    : QWidget(parent)
    , m_gameService(gameService)        // 游戏服务引用（可能为nullptr）
    , m_authService(authService)        // 认证服务引用
    , m_autoRefreshTimer(new QTimer(this))  // 自动刷新定时器
    , m_gameTypeChangeTimer(nullptr)    // 游戏类型切换定时器（按需创建）

    // === 颜色主题配置 ===
    /* 颜色主题字符串格式：
     * 所有颜色都使用十六进制格式，如 "#4A90E2"
     * 这些颜色值来自Config类的配置，确保整个应用的一致性
     */
    , m_primaryColor("#4A90E2")         // 主色调：蓝色系
    , m_secondaryColor("#7ED321")       // 辅助色：绿色系
    , m_backgroundColor("#2C3E50")      // 背景色：深蓝灰色
    , m_textColor("#ECF0F1")            // 文字色：浅灰白色
    , m_errorColor("#E74C3C")           // 错误色：红色系
    , m_successColor("#27AE60")         // 成功色：绿色系
    , m_warningColor("#F39C12")         // 警告色：橙色系

    // === 状态和分页配置 ===
    , m_autoRefreshEnabled(true)        // 默认启用自动刷新
    , m_currentPage(1)                  // 当前页码
    , m_totalPages(1)                   // 总页数
    , m_pageSize(50)                    // 每页显示数量
{
    // === 初始化UI组件 ===
    setupUI();          // 创建和布局所有UI组件
    applyStyles();      // 应用样式表和主题

    // === 建立信号槽连接（如果GameService可用） ===
    if (m_gameService) {
        connectGameService();
    }

    // === 自动刷新定时器配置 ===
    /* 自动刷新机制：
     * - 每30秒（30000毫秒）自动刷新一次服务器列表
     * - 用户可以通过UI按钮开启/关闭自动刷新
     * - 只有在UI可用状态下才会执行自动刷新
     */
    connect(m_autoRefreshTimer, &QTimer::timeout, this, &GameServerWidget::onAutoRefreshTimer);
    m_autoRefreshTimer->start(30000); // 30秒自动刷新

    // === 初始状态设置 ===
    if (m_gameService) {
        // 如果GameService可用，立即加载服务器列表
        onRefreshClicked();
    } else {
        // 如果GameService不可用，显示等待认证的状态
        updateStatusMessage("请先登录以查看游戏服务器列表", "info");
        setUIEnabled(false);
    }
}

GameServerWidget::~GameServerWidget()
{
    // 停止定时器
    if (m_autoRefreshTimer) {
        m_autoRefreshTimer->stop();
    }
    if (m_gameTypeChangeTimer) {
        m_gameTypeChangeTimer->stop();
    }
    // QTimer和其他UI组件通过Qt的父子关系自动管理
}

/**
 * @brief 设置游戏服务实例
 * @param gameService 游戏服务指针
 *
 * 当GameService在登录成功后创建时调用此方法，
 * 建立信号槽连接并启用UI功能
 */
void GameServerWidget::setGameService(GameService *gameService)
{
    // 如果已有GameService，先断开连接
    if (m_gameService) {
        disconnect(m_gameService, nullptr, this, nullptr);
    }

    // 设置新的GameService
    m_gameService = gameService;

    // 建立信号槽连接
    if (m_gameService) {
        connectGameService();

        // 启用UI并刷新服务器列表
        setUIEnabled(true);
        updateStatusMessage("游戏服务已连接，正在加载服务器列表...", "info");
        onRefreshClicked();

        qDebug() << "GameServerWidget: GameService connected and UI enabled";
    } else {
        // 如果GameService为空，禁用UI
        setUIEnabled(false);
        updateStatusMessage("游戏服务未连接，请先登录", "warning");
    }
}

/**
 * @brief 建立GameService的信号槽连接
 *
 * 连接GameService的所有相关信号到对应的槽函数
 */
void GameServerWidget::connectGameService()
{
    if (!m_gameService) {
        return;
    }

    // 连接GameService的信号到对应的槽函数
    // === 连接传统GameService信号槽 ===
    connect(m_gameService, &GameService::gameServersReceived,
            this, &GameServerWidget::onGameServersReceived);
    connect(m_gameService, &GameService::gameJoinSucceeded,
            this, &GameServerWidget::onGameJoinSucceeded);
    connect(m_gameService, &GameService::gameJoinFailed,
            this, &GameServerWidget::onGameJoinFailed);
    connect(m_gameService, &GameService::requestFailed,
            this, &GameServerWidget::onRequestFailed);

    // === 连接服务发现API信号槽 ===
    connect(m_gameService, &GameService::gameServicesDiscovered,
            this, &GameServerWidget::onGameServicesDiscovered);
    connect(m_gameService, &GameService::serviceDiscoveryError,
            this, &GameServerWidget::onServiceDiscoveryError);

    qDebug() << "GameServerWidget: GameService signals connected";
}

void GameServerWidget::setupUI()
{
    m_mainLayout = new QVBoxLayout(this);
    m_mainLayout->setSpacing(8);
    m_mainLayout->setContentsMargins(8, 8, 8, 8); // 最小边距，最大化内容空间

    // 优化的页面头部区域
    QWidget *headerWidget = new QWidget();
    headerWidget->setObjectName("pageHeader");
    QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget);
    headerLayout->setContentsMargins(8, 8, 8, 8); // 统一边距
    headerLayout->setSpacing(20);

    // 页面标题和副标题
    QWidget *titleWidget = new QWidget();
    QVBoxLayout *titleLayout = new QVBoxLayout(titleWidget);
    titleLayout->setContentsMargins(0, 0, 0, 0);
    titleLayout->setSpacing(5);

    QLabel *pageTitle = new QLabel("🎮 游戏服务器");
    pageTitle->setObjectName("pageTitle");
    titleLayout->addWidget(pageTitle);

    QLabel *pageSubtitle = new QLabel("发现并加入游戏服务器");
    pageSubtitle->setObjectName("pageSubtitle");
    titleLayout->addWidget(pageSubtitle);

    headerLayout->addWidget(titleWidget);
    headerLayout->addStretch();

    // 快速操作按钮
    QPushButton *quickRefreshBtn = new QPushButton("🔄 快速刷新");
    quickRefreshBtn->setObjectName("quickActionBtn");
    quickRefreshBtn->setToolTip("立即刷新服务器列表");
    connect(quickRefreshBtn, &QPushButton::clicked, this, &GameServerWidget::onRefreshClicked);
    headerLayout->addWidget(quickRefreshBtn);

    QPushButton *quickCreateBtn = new QPushButton("➕ 创建房间");
    quickCreateBtn->setObjectName("quickActionBtn");
    quickCreateBtn->setToolTip("创建新的游戏房间（功能开发中）");
    connect(quickCreateBtn, &QPushButton::clicked, this, &GameServerWidget::onCreateRoomClicked);
    headerLayout->addWidget(quickCreateBtn);

    m_mainLayout->addWidget(headerWidget);

    // 设置过滤器
    setupFilters();

    // 主分割器
    m_mainSplitter = new QSplitter(Qt::Horizontal, this);
    m_mainSplitter->setObjectName("mainSplitter");
    m_mainSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_mainLayout->addWidget(m_mainSplitter, 1); // 使用比例拉伸

    // 左侧：服务器列表
    setupServerTable();

    // 右侧：服务器详情和状态
    QWidget *rightWidget = new QWidget();
    QVBoxLayout *rightLayout = new QVBoxLayout(rightWidget);
    rightLayout->setSpacing(8);
    rightLayout->setContentsMargins(0, 0, 0, 0); // 右侧容器无边距，由子组件控制

    setupServerDetails();
    setupStatusPanel();

    rightLayout->addWidget(m_serverDetailsGroup, 1); // 详情区域占更多空间
    rightLayout->addWidget(m_statusGroup); // 状态区域固定大小

    m_mainSplitter->addWidget(rightWidget);

    // 优化分割器比例 - 平衡服务器列表和详情展示
    int totalWidth = Config::getDefaultWindowSize().width() - Config::getSidebarExpandedWidth();
    int leftWidth = static_cast<int>(totalWidth * 0.70);  // 70% 给服务器列表
    int rightWidth = static_cast<int>(totalWidth * 0.30); // 30% 给详情面板
    m_mainSplitter->setSizes({leftWidth, rightWidth});
    
    // 设置分割器的最小尺寸，确保两边都可见
    m_mainSplitter->setChildrenCollapsible(false);
}

/**
 * @brief 设置筛选器UI组件
 *
 * 创建游戏服务器筛选器界面，包括游戏类型、状态和排序选项。
 * 每个筛选器都包含用户友好的图标和文本标签。
 */
void GameServerWidget::setupFilters()
{
    // === 创建现代化筛选器容器 ===
    m_filterGroup = new QWidget();
    m_filterGroup->setObjectName("modernFilterCard");
    m_filterLayout = new QHBoxLayout(m_filterGroup);
    m_filterLayout->setSpacing(20);                    // 适度减少间距，使布局更紧凑
    m_filterLayout->setContentsMargins(12, 10, 12, 10); // 优化边距，提供更好的视觉平衡

    // === 筛选器标题 ===
    QLabel *filterTitle = new QLabel("🔍 筛选条件");
    filterTitle->setObjectName("filterTitle");
    m_filterLayout->addWidget(filterTitle);

    // === 视觉分隔线 ===
    QFrame *separator = new QFrame();
    separator->setObjectName("filterSeparator");
    separator->setFrameShape(QFrame::VLine);
    separator->setFrameShadow(QFrame::Sunken);
    m_filterLayout->addWidget(separator);

    // === 游戏类型筛选器 ===
    /* 游戏类型下拉框选项配置：
     * 每个选项包含：
     * - 显示文本：用户看到的友好文本（包含emoji图标）
     * - 数据值：发送给API的实际值
     *
     * 选项映射：
     * "🎮 全部游戏" → ""（空字符串，表示不筛选）
     * "🐍 贪吃蛇" → "snake"
     * "🧩 俄罗斯方块" → "tetris"
     * "🧠 益智游戏" → "puzzle"
     */
    QWidget *gameTypeWidget = createFilterWidget("🎮 游戏类型", "gameType");
    QVBoxLayout *gameTypeLayout = qobject_cast<QVBoxLayout*>(gameTypeWidget->layout());

    m_gameTypeCombo = new QComboBox();
    m_gameTypeCombo->setObjectName("modernFilterCombo");
    m_gameTypeCombo->setMinimumWidth(140);
    m_gameTypeCombo->setToolTip("选择要查看的游戏类型\n选择后将自动刷新服务器列表");

    // 添加游戏类型选项（显示文本，数据值）
    m_gameTypeCombo->addItem("🎮 全部游戏", "");        // 不筛选
    m_gameTypeCombo->addItem("🐍 贪吃蛇游戏", "snake");     // 贪吃蛇游戏
    m_gameTypeCombo->addItem("🧩 俄罗斯方块", "tetris"); // 俄罗斯方块
    m_gameTypeCombo->addItem("🧠 益智游戏", "puzzle");   // 益智类游戏

    // 默认选择"全部游戏"，避免因特定游戏类型没有服务器而显示空列表
    m_gameTypeCombo->setCurrentIndex(0);  // 选择"🎮 全部游戏"

    // 连接选择变化事件 - 游戏类型改变时自动刷新服务器列表
    connect(m_gameTypeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &GameServerWidget::onGameTypeChanged);
    gameTypeLayout->addWidget(m_gameTypeCombo);
    m_filterLayout->addWidget(gameTypeWidget);

    // === 地区筛选器已删除 ===
    // 用户可以在服务器列表中看到地区信息，根据需要自行选择

    // === 状态筛选器 ===
    /* 服务器状态筛选器选项：
     * 选项映射：
     * "📊 全部状态" → ""（空字符串，不筛选）
     * "🟢 在线" → "online"（可以连接的服务器）
     * "🔧 维护中" → "maintenance"（维护状态的服务器）
     *
     * 状态说明：
     * - online：正常运行，可以加入游戏
     * - maintenance：正在维护，暂时不可用
     */
    QWidget *statusWidget = createFilterWidget("状态", "status");
    QVBoxLayout *statusLayout = qobject_cast<QVBoxLayout*>(statusWidget->layout());

    m_statusCombo = new QComboBox();
    m_statusCombo->setObjectName("modernFilterCombo");
    m_statusCombo->setMinimumWidth(110);

    // 添加状态选项（显示文本，数据值）
    m_statusCombo->addItem("📊 全部状态", "");              // 不筛选
    m_statusCombo->addItem("🟢 在线", "online");           // 在线服务器
    m_statusCombo->addItem("🔧 维护中", "maintenance");     // 维护中服务器

    connect(m_statusCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &GameServerWidget::onFilterChanged);
    statusLayout->addWidget(m_statusCombo);
    m_filterLayout->addWidget(statusWidget);

    // === 服务健康状态筛选器 ===
    /* 健康状态筛选器选项：
     * 根据服务发现API的healthy参数：
     * "💚 仅可用服务" → true（只显示通过健康检查的游戏服务）
     * "⚠️ 包含异常服务" → false（包含健康检查失败的服务）
     *
     * 健康状态说明：
     * - 可用服务：通过心跳检查，可以正常连接和游戏
     * - 异常服务：心跳检查失败，可能无法连接
     */
    QWidget *healthyWidget = createFilterWidget("💚 服务状态", "healthy");
    QVBoxLayout *healthyLayout = qobject_cast<QVBoxLayout*>(healthyWidget->layout());

    m_healthyOnlyCombo = new QComboBox();
    m_healthyOnlyCombo->setObjectName("modernFilterCombo");
    m_healthyOnlyCombo->setMinimumWidth(140);
    m_healthyOnlyCombo->setToolTip("筛选服务健康状态\n💚 仅可用服务：只显示运行正常的游戏服务\n⚠️ 包含异常服务：显示所有服务（含异常）");

    // 添加健康状态选项（显示文本，数据值）
    m_healthyOnlyCombo->addItem("💚 仅可用服务", true);       // 只显示健康的游戏服务
    m_healthyOnlyCombo->addItem("⚠️ 包含异常服务", false);    // 包含不健康的服务
    m_healthyOnlyCombo->setCurrentIndex(0);  // 默认选择"仅可用服务"

    connect(m_healthyOnlyCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &GameServerWidget::onFilterChanged);
    healthyLayout->addWidget(m_healthyOnlyCombo);
    m_filterLayout->addWidget(healthyWidget);

    // === 删除传统列表选项，默认使用服务发现 ===
    // 根据用户需求，移除传统列表选项，避免布局混乱
    // 现在默认且仅使用服务发现模式

    // === 排序筛选器 ===
    /* 排序选项配置：
     * 选项映射：
     * "⚡ 按延迟" → "ping"（按延迟从低到高排序）
     * "👥 按玩家数" → "players"（按在线玩家数排序）
     * "📝 按名称" → "name"（按服务器名称字母顺序排序）
     *
     * 排序说明：
     * - ping：延迟越低排名越靠前，适合追求流畅体验
     * - players：玩家数越多排名越靠前，适合寻找热门服务器
     * - name：按字母顺序排序，便于查找特定服务器
     */
    QWidget *sortWidget = createFilterWidget("排序", "sort");
    QVBoxLayout *sortLayout = qobject_cast<QVBoxLayout*>(sortWidget->layout());

    m_sortByCombo = new QComboBox();
    m_sortByCombo->setObjectName("modernFilterCombo");
    m_sortByCombo->setMinimumWidth(120);

    // 添加排序选项（显示文本，数据值）
    m_sortByCombo->addItem("⚡ 按延迟", "ping");         // 按延迟排序
    m_sortByCombo->addItem("👥 按玩家数", "players");    // 按玩家数排序
    m_sortByCombo->addItem("📝 按名称", "name");        // 按名称排序

    connect(m_sortByCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &GameServerWidget::onFilterChanged);
    sortLayout->addWidget(m_sortByCombo);
    m_filterLayout->addWidget(sortWidget);

    m_filterLayout->addStretch();

    // 操作按钮区域
    QWidget *actionWidget = new QWidget();
    QHBoxLayout *actionLayout = new QHBoxLayout(actionWidget);
    actionLayout->setSpacing(12);
    actionLayout->setContentsMargins(0, 0, 0, 0);

    // 刷新按钮
    m_refreshButton = new QPushButton("🔄 刷新列表", this);
    m_refreshButton->setObjectName("primaryButton");
    m_refreshButton->setMinimumWidth(120);
    connect(m_refreshButton, &QPushButton::clicked, this, &GameServerWidget::onRefreshClicked);
    actionLayout->addWidget(m_refreshButton);

    // 自动刷新按钮
    m_autoRefreshButton = new QPushButton("🔄 自动刷新: 开", this);
    m_autoRefreshButton->setObjectName("toggleButton");
    m_autoRefreshButton->setCheckable(true);
    m_autoRefreshButton->setChecked(true);
    m_autoRefreshButton->setMinimumWidth(140);
    connect(m_autoRefreshButton, &QPushButton::toggled, [this](bool checked) {
        m_autoRefreshEnabled = checked;
        m_autoRefreshButton->setText(checked ? "🔄 自动刷新: 开" : "⏸️ 自动刷新: 关");
        if (checked) {
            m_autoRefreshTimer->start(30000);
        } else {
            m_autoRefreshTimer->stop();
        }
    });
    actionLayout->addWidget(m_autoRefreshButton);

    m_filterLayout->addWidget(actionWidget);

    m_mainLayout->addWidget(m_filterGroup);

    // 添加分页控件
    setupPagination();
}

void GameServerWidget::setupPagination()
{
    // 现代化分页控件 - 无边框设计
    QWidget *paginationWidget = new QWidget();
    paginationWidget->setObjectName("modernPaginationWidget");
    m_paginationLayout = new QHBoxLayout(paginationWidget);
    m_paginationLayout->setSpacing(15);
    m_paginationLayout->setContentsMargins(8, 8, 8, 8); // 统一边距

    // 页面大小选择 - 现代化设计
    QLabel *pageSizeLabel = new QLabel("每页显示:");
    pageSizeLabel->setObjectName("paginationLabel");
    m_paginationLayout->addWidget(pageSizeLabel);

    m_pageSizeCombo = new QComboBox();
    m_pageSizeCombo->setObjectName("modernPaginationCombo");
    m_pageSizeCombo->addItem("25", 25);
    m_pageSizeCombo->addItem("50", 50);
    m_pageSizeCombo->addItem("100", 100);
    m_pageSizeCombo->setCurrentIndex(1); // 默认50
    connect(m_pageSizeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &GameServerWidget::onPageSizeChanged);
    m_paginationLayout->addWidget(m_pageSizeCombo);

    m_paginationLayout->addStretch();

    // 分页按钮
    m_firstPageButton = new QPushButton("首页", this);
    m_firstPageButton->setObjectName("paginationButton");
    connect(m_firstPageButton, &QPushButton::clicked, this, &GameServerWidget::onFirstPageClicked);
    m_paginationLayout->addWidget(m_firstPageButton);

    m_prevPageButton = new QPushButton("上一页", this);
    m_prevPageButton->setObjectName("paginationButton");
    connect(m_prevPageButton, &QPushButton::clicked, this, &GameServerWidget::onPrevPageClicked);
    m_paginationLayout->addWidget(m_prevPageButton);

    // 页面信息
    m_pageInfoLabel = new QLabel("第 1 页，共 1 页", this);
    m_pageInfoLabel->setObjectName("pageInfoLabel");
    m_pageInfoLabel->setMinimumWidth(120);
    m_pageInfoLabel->setAlignment(Qt::AlignCenter);
    m_paginationLayout->addWidget(m_pageInfoLabel);

    m_nextPageButton = new QPushButton("下一页", this);
    m_nextPageButton->setObjectName("paginationButton");
    connect(m_nextPageButton, &QPushButton::clicked, this, &GameServerWidget::onNextPageClicked);
    m_paginationLayout->addWidget(m_nextPageButton);

    m_lastPageButton = new QPushButton("末页", this);
    m_lastPageButton->setObjectName("paginationButton");
    connect(m_lastPageButton, &QPushButton::clicked, this, &GameServerWidget::onLastPageClicked);
    m_paginationLayout->addWidget(m_lastPageButton);

    m_mainLayout->addWidget(paginationWidget);

    // 初始状态
    updatePaginationControls();
}

void GameServerWidget::setupServerTable()
{
    // 现代化服务器列表容器 - 无边框设计
    m_serverListGroup = new QWidget();
    m_serverListGroup->setObjectName("modernServerListWidget");
    m_serverListGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    QVBoxLayout *serverLayout = new QVBoxLayout(m_serverListGroup);
    serverLayout->setSpacing(5);
    serverLayout->setContentsMargins(8, 8, 8, 8); // 统一边距

    // 服务器表格
    m_serverTable = new QTableWidget(this);
    m_serverTable->setObjectName("serverTable");
    m_serverTable->setColumnCount(8);
    QStringList headers = {"🏷️ 服务器名称", "🎮 游戏类型", "🌍 地区", "⚡ 延迟", "👥 玩家数", "📊 负载", "🔘 状态", "📦 版本"};
    m_serverTable->setHorizontalHeaderLabels(headers);
    m_serverTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_serverTable->setSelectionMode(QAbstractItemView::SingleSelection);
    m_serverTable->setAlternatingRowColors(true);
    m_serverTable->setSortingEnabled(true);
    m_serverTable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    // 设置表头
    QHeaderView *header = m_serverTable->horizontalHeader();
    header->setStretchLastSection(true);
    header->setSectionResizeMode(0, QHeaderView::Stretch); // 服务器名称自适应
    header->setSectionResizeMode(1, QHeaderView::ResizeToContents); // 游戏类型
    header->setSectionResizeMode(2, QHeaderView::ResizeToContents); // 地区
    header->setSectionResizeMode(3, QHeaderView::ResizeToContents); // 延迟
    header->setSectionResizeMode(4, QHeaderView::ResizeToContents); // 玩家数
    header->setSectionResizeMode(5, QHeaderView::ResizeToContents); // 负载
    header->setSectionResizeMode(6, QHeaderView::ResizeToContents); // 状态
    header->setSectionResizeMode(7, QHeaderView::ResizeToContents); // 版本

    m_serverTable->verticalHeader()->setVisible(false);

    connect(m_serverTable, &QTableWidget::itemSelectionChanged, 
            this, &GameServerWidget::onServerSelectionChanged);

    serverLayout->addWidget(m_serverTable);

    // 加入游戏按钮
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addStretch();

    m_joinButton = new QPushButton("🎮 加入游戏", this);
    m_joinButton->setObjectName("primaryButton");
    m_joinButton->setEnabled(false);
    m_joinButton->setMinimumWidth(120);  // 确保按钮有足够的宽度
    m_joinButton->setToolTip("选择服务器后点击加入游戏\n将通过API Gateway进行认证");
    connect(m_joinButton, &QPushButton::clicked, this, &GameServerWidget::onJoinClicked);
    buttonLayout->addWidget(m_joinButton);

    serverLayout->addLayout(buttonLayout);

    m_mainSplitter->addWidget(m_serverListGroup);
}

void GameServerWidget::setupServerDetails()
{
    // 现代化详情面板 - 无边框设计
    m_serverDetailsGroup = new QWidget();
    m_serverDetailsGroup->setObjectName("modernDetailsWidget");
    m_serverDetailsGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    QVBoxLayout *detailsLayout = new QVBoxLayout(m_serverDetailsGroup);
    detailsLayout->setContentsMargins(8, 8, 8, 8); // 统一边距

    m_serverDetailsText = new QTextEdit(this);
    m_serverDetailsText->setObjectName("detailsText");
    m_serverDetailsText->setReadOnly(true);
    m_serverDetailsText->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_serverDetailsText->setText("🔍 请选择一个服务器查看详细信息\n\n"
                                "在左侧服务器列表中点击任意服务器，\n"
                                "这里将显示该服务器的详细配置信息。");

    detailsLayout->addWidget(m_serverDetailsText);
}

void GameServerWidget::setupStatusPanel()
{
    // 现代化状态面板 - 无边框设计
    m_statusGroup = new QWidget();
    m_statusGroup->setObjectName("modernStatusWidget");
    m_statusGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    QVBoxLayout *statusLayout = new QVBoxLayout(m_statusGroup);
    statusLayout->setSpacing(8);
    statusLayout->setContentsMargins(8, 8, 8, 8); // 统一边距

    // 统计信息网格
    QWidget *statsWidget = new QWidget();
    QGridLayout *statsGrid = new QGridLayout(statsWidget);
    statsGrid->setSpacing(8);                          // 使用固定间距，确保一致性
    statsGrid->setContentsMargins(4, 4, 4, 4);         // 添加适度内边距

    // 总服务器
    QLabel *serverIcon = new QLabel("🖥️");
    serverIcon->setAlignment(Qt::AlignCenter);
    m_totalServersLabel = new QLabel("总服务器: 0", this);
    m_totalServersLabel->setObjectName("statLabel");
    statsGrid->addWidget(serverIcon, 0, 0);
    statsGrid->addWidget(m_totalServersLabel, 0, 1);

    // 在线服务器
    QLabel *onlineIcon = new QLabel("🟢");
    onlineIcon->setAlignment(Qt::AlignCenter);
    m_onlineServersLabel = new QLabel("在线服务器: 0", this);
    m_onlineServersLabel->setObjectName("statLabel");
    statsGrid->addWidget(onlineIcon, 1, 0);
    statsGrid->addWidget(m_onlineServersLabel, 1, 1);

    // 总玩家数
    QLabel *playersIcon = new QLabel("👥");
    playersIcon->setAlignment(Qt::AlignCenter);
    m_totalPlayersLabel = new QLabel("总玩家数: 0", this);
    m_totalPlayersLabel->setObjectName("statLabel");
    statsGrid->addWidget(playersIcon, 2, 0);
    statsGrid->addWidget(m_totalPlayersLabel, 2, 1);

    statusLayout->addWidget(statsWidget);

    // 分隔线
    QFrame *line = new QFrame(this);
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    line->setObjectName("separator");
    statusLayout->addWidget(line);

    // 状态显示
    m_statusLabel = new QLabel("🔄 准备就绪", this);
    m_statusLabel->setObjectName("statusLabel");
    m_statusLabel->setWordWrap(true);
    m_statusLabel->setAlignment(Qt::AlignCenter);
    statusLayout->addWidget(m_statusLabel);

    m_progressBar = new QProgressBar(this);
    m_progressBar->setVisible(false);
    m_progressBar->setObjectName("progressBar");
    statusLayout->addWidget(m_progressBar);
}

void GameServerWidget::onRefreshClicked()
{
    // 检查GameService是否可用
    if (!m_gameService) {
        updateStatusMessage("游戏服务未连接，请先登录", "warning");
        return;
    }

    setUIEnabled(false);
    m_progressBar->setVisible(true);

    // 获取筛选条件
    QString gameType = m_gameTypeCombo->currentData().toString();
    bool healthyOnly = m_healthyOnlyCombo->currentData().toBool();

    // === 使用服务发现API获取游戏服务器 ===
    updateStatusMessage("🔍 正在查找游戏服务器...", "info");

    qDebug() << "GameServerWidget: 服务发现查询 - 游戏类型:" << gameType
             << "仅健康服务:" << healthyOnly;

    // 调用服务发现API
    m_gameService->discoverGameServices(gameType, healthyOnly);
}

void GameServerWidget::onJoinClicked()
{
    GameService::GameServer server = getSelectedServer();
    if (server.serverId.isEmpty()) {
        QMessageBox::warning(this, "警告", "请选择一个服务器");
        return;
    }

    if (server.status != "online") {
        QMessageBox::warning(this, "警告", "选择的服务器不在线，无法加入游戏");
        return;
    }

    // 检查服务器容量，但给服务发现的服务器更宽松的检查
    double occupancyRate = (double)server.currentPlayers / server.maxPlayers;
    if (occupancyRate >= 0.95) { // 95%以上才认为满员
        QString warningMsg = QString("服务器 \"%1\" 接近满员状态 (%2/%3 人)\n\n"
                                   "是否仍要尝试加入？\n"
                                   "注意：可能需要等待或连接失败。")
                            .arg(server.name)
                            .arg(server.currentPlayers)
                            .arg(server.maxPlayers);

        QMessageBox::StandardButton reply = QMessageBox::question(this, "服务器接近满员", warningMsg,
                                                                QMessageBox::Yes | QMessageBox::No);
        if (reply != QMessageBox::Yes) {
            return;
        }
    }

    // 根据游戏类型显示不同的确认信息
    QString gameTypeIcon = "🎮";
    QString gameTypeName = server.gameType.toUpper();
    QString specialInfo = "";
    QString connectionInfo = "";

    if (server.gameType.toLower() == "snake") {
        gameTypeIcon = "🐍";
        gameTypeName = "贪吃蛇游戏";
        specialInfo = "\n\n🎯 Snake游戏特色功能：\n"
                     "• 🕹️ 多人实时对战\n"
                     "• 🏠 可创建或加入房间\n"
                     "• 💬 游戏内实时聊天\n"
                     "• 🏆 实时排行榜系统\n"
                     "• ⚙️ 多种游戏模式\n"
                     "• 🌐 WebSocket长连接技术";
        
        connectionInfo = "\n\n🔗 连接流程说明：\n"
                        "1️⃣ 通过API Gateway进行游戏认证\n"
                        "2️⃣ 获取游戏令牌和WebSocket地址\n"
                        "3️⃣ 建立WebSocket长连接\n"
                        "4️⃣ 进入游戏大厅，可创建或加入房间\n"
                        "5️⃣ 开始多人实时对战";
    } else if (server.gameType.toLower() == "tetris") {
        gameTypeIcon = "🧩";
        gameTypeName = "俄罗斯方块";
        specialInfo = "\n\n🎯 俄罗斯方块特色功能：\n"
                     "• ⚡ 竞速对战模式\n"
                     "• 🏁 计时挑战赛\n"
                     "• 👥 团队协作模式\n"
                     "• 🎵 音效同步\n"
                     "• 📊 技能统计";
    } else if (server.gameType.toLower() == "puzzle") {
        gameTypeIcon = "🧠";
        gameTypeName = "益智游戏";
        specialInfo = "\n\n🎯 益智游戏特色功能：\n"
                     "• 🤔 逻辑思维挑战\n"
                     "• 🏆 智力比拼竞赛\n"
                     "• ⏰ 限时答题模式\n"
                     "• 📊 进度追踪系统\n"
                     "• 🎯 难度级别选择";
    }

    QString confirmMessage = QString("%1 确定要加入服务器 \"%2\" 吗？\n\n"
                                   "📋 服务器信息：\n"
                                   "• 游戏类型：%3 %4\n"
                                   "• 服务器地区：%5\n"
                                   "• 在线玩家：%6/%7 人\n"
                                   "• 网络延迟：%8ms\n"
                                   "• 服务器负载：%9%%\n"
                                   "• 服务器版本：%10"
                                   "%11%12")
                            .arg(gameTypeIcon)
                            .arg(server.name)
                            .arg(gameTypeIcon)
                            .arg(gameTypeName)
                            .arg(server.region.toUpper())
                            .arg(server.currentPlayers)
                            .arg(server.maxPlayers)
                            .arg(server.ping >= 0 ? QString("%1ms").arg(server.ping) : "未知")
                            .arg(QString::number(server.loadPercentage, 'f', 1))
                            .arg(server.version)
                            .arg(specialInfo)
                            .arg(connectionInfo);

    QMessageBox::StandardButton reply = QMessageBox::question(this,
                                                            QString("%1 加入游戏").arg(gameTypeIcon),
                                                            confirmMessage,
                                                            QMessageBox::Yes | QMessageBox::No);

    if (reply != QMessageBox::Yes) {
        return;
    }

    // 保存选中的服务器信息
    m_selectedServer = server;

    qDebug() << "GameServerWidget: Starting game join process for" << server.gameType
             << "server:" << server.serverId;

    // 发出游戏加入请求信号，让MainWindow处理认证进度页面
    emit gameJoinRequested(server.gameType);
}

/**
 * @brief 创建房间按钮点击槽函数
 *
 * 处理用户点击"创建房间"按钮的事件。
 * 目前显示开发中提示，未来可扩展为完整的房间创建功能。
 */

void GameServerWidget::onCreateRoomClicked()
{
    /* 创建房间功能说明：
     *
     * 当前实现：
     * - 显示功能开发中的提示信息
     * - 为用户提供友好的反馈
     *
     * 未来可扩展的功能：
     * 1. 打开创建房间对话框
     *    - 房间名称设置
     *    - 游戏类型选择
     *    - 最大玩家数设置
     *    - 房间密码设置（可选）
     *
     * 2. 调用GameService API
     *    - createGameRoom(roomConfig)
     *    - 处理房间创建响应
     *
     * 3. 界面状态更新
     *    - 显示创建进度
     *    - 成功后跳转到房间管理界面
     *    - 失败时显示错误信息
     *
     * 4. 可能的信号发射
     *    - emit createRoomRequested(roomConfig)
     *    - 让主窗口或其他组件处理房间创建
     */

    // === 当前实现：显示开发中提示 ===
    QMessageBox::information(this, "创建房间",
        "🚧 创建房间功能正在开发中...\n\n"
        "即将支持的功能：\n"
        "• 自定义房间名称\n"
        "• 选择游戏类型\n"
        "• 设置玩家数量\n"
        "• 房间密码保护\n\n"
        "敬请期待！");

    // === 未来扩展示例代码（注释状态） ===
    /*
    // 创建房间配置对话框
    CreateRoomDialog dialog(this);
    if (dialog.exec() == QDialog::Accepted) {
        RoomConfig config = dialog.getRoomConfig();

        // 显示创建进度
        setUIEnabled(false);
        m_progressBar->setVisible(true);
        m_statusLabel->setText("正在创建房间...");
        m_statusLabel->setStyleSheet("color: #3498DB;");

        // 调用创建房间API
        m_gameService->createGameRoom(config);
    }
    */
}

void GameServerWidget::onFilterChanged()
{
    onRefreshClicked();
}

void GameServerWidget::onGameTypeChanged()
{
    // 重置到第一页
    m_currentPage = 1;

    // 获取选中的游戏类型
    QString selectedGameType = m_gameTypeCombo->currentData().toString();
    QString selectedGameTypeName = m_gameTypeCombo->currentText();

    qDebug() << "GameServerWidget: Game type changed to:" << selectedGameType
             << "(" << selectedGameTypeName << ")";

    // 清空当前服务器列表，显示加载状态
    m_serverTable->setRowCount(0);
    m_servers.clear();

    // 清空服务器详情显示，根据游戏类型显示相应提示
    m_serverDetailsText->clear();
    
    // 根据选择的游戏类型更新UI状态和提示信息
    if (selectedGameType == "snake") {
        // 选择Snake游戏时的特定处理
        updateStatusMessage("🐍 正在获取Snake游戏服务器列表...", "info");
        
        m_serverDetailsText->setHtml(
            "<h3>🐍 Snake游戏服务器</h3>"
            "<p>正在加载Snake游戏服务器列表...</p>"
            "<br/>"
            "<p><b>🎮 游戏特色：</b></p>"
            "<ul>"
            "<li>🕹️ 多人实时对战</li>"
            "<li>💬 游戏内聊天</li>"
            "<li>🏆 排行榜系统</li>"
            "<li>🎯 多种游戏模式</li>"
            "<li>🌐 WebSocket长连接</li>"
            "</ul>"
            "<p><i>选择一个服务器查看详细信息...</i></p>");

    } else if (selectedGameType == "tetris") {
        // 选择俄罗斯方块游戏
        updateStatusMessage("🧩 正在获取俄罗斯方块游戏服务器列表...", "info");
        
        m_serverDetailsText->setHtml(
            "<h3>🧩 俄罗斯方块游戏服务器</h3>"
            "<p>正在加载俄罗斯方块游戏服务器列表...</p>"
            "<br/>"
            "<p><b>🎮 游戏特色：</b></p>"
            "<ul>"
            "<li>⚡ 竞速对战</li>"
            "<li>🏁 计时挑战</li>"
            "<li>👥 团队模式</li>"
            "<li>🎵 音效同步</li>"
            "</ul>"
            "<p><i>选择一个服务器查看详细信息...</i></p>");

    } else if (selectedGameType == "puzzle") {
        // 选择益智游戏
        updateStatusMessage("🧠 正在获取益智游戏服务器列表...", "info");
        
        m_serverDetailsText->setHtml(
            "<h3>🧠 益智游戏服务器</h3>"
            "<p>正在加载益智游戏服务器列表...</p>"
            "<br/>"
            "<p><b>🎮 游戏特色：</b></p>"
            "<ul>"
            "<li>🤔 逻辑挑战</li>"
            "<li>🏆 智力比拼</li>"
            "<li>⏰ 限时答题</li>"
            "<li>📊 进度追踪</li>"
            "</ul>"
            "<p><i>选择一个服务器查看详细信息...</i></p>");

    } else if (selectedGameType.isEmpty()) {
        // 选择全部游戏时
        updateStatusMessage("🎮 正在获取所有游戏服务器列表...", "info");
        
        m_serverDetailsText->setHtml(
            "<h3>🎮 所有游戏服务器</h3>"
            "<p>正在加载所有类型的游戏服务器...</p>"
            "<br/>"
            "<p><b>🌟 支持的游戏：</b></p>"
            "<ul>"
            "<li>🐍 Snake - 经典贪吃蛇</li>"
            "<li>🧩 Tetris - 俄罗斯方块</li>"
            "<li>🧠 Puzzle - 益智挑战</li>"
            "</ul>"
            "<p><i>选择一个服务器查看详细信息...</i></p>");

    } else {
        // 其他游戏类型的通用处理
        updateStatusMessage(QString("正在获取%1服务器列表...").arg(selectedGameTypeName), "info");
        
        m_serverDetailsText->setHtml(
            QString("<h3>%1</h3>").arg(selectedGameTypeName) +
            "<p>正在加载服务器列表...</p>" +
            "<br/>" +
            "<p><i>选择一个服务器查看详细信息...</i></p>");
    }

    // 重置统计信息显示，使用游戏类型特定的图标
    QString gameIcon = selectedGameType == "snake" ? "🐍" : 
                      selectedGameType == "tetris" ? "🧩" : 
                      selectedGameType == "puzzle" ? "🧠" : "🎮";
    
    m_totalServersLabel->setText(QString("%1 总服务器: --").arg(gameIcon));
    m_onlineServersLabel->setText(QString("%1 在线服务器: --").arg(gameIcon));
    m_totalPlayersLabel->setText(QString("%1 总玩家: --").arg(gameIcon));

    // 设置延迟加载机制，避免频繁请求
    if (m_gameTypeChangeTimer) {
        m_gameTypeChangeTimer->stop();
    } else {
        m_gameTypeChangeTimer = new QTimer(this);
        m_gameTypeChangeTimer->setSingleShot(true);
        connect(m_gameTypeChangeTimer, &QTimer::timeout, this, [this]() {
            // 延迟执行刷新，提供更好的用户体验
            onRefreshClicked();
        });
    }

    // 立即更新UI状态，然后延迟300ms执行网络请求
    m_serverTable->clearSelection();
    
    // 延迟300ms刷新服务器列表，给用户选择的时间
    m_gameTypeChangeTimer->start(300);
}

/**
 * @brief 更新状态消息
 * @param message 要显示的消息
 * @param type 消息类型（info、success、warning、error）
 */
void GameServerWidget::updateStatusMessage(const QString &message, const QString &type)
{
    m_statusLabel->setText(message);

    // 根据消息类型设置不同的颜色
    if (type == "info") {
        m_statusLabel->setStyleSheet("color: #3498DB;");  // 蓝色
    } else if (type == "success") {
        m_statusLabel->setStyleSheet("color: #27AE60;");  // 绿色
    } else if (type == "warning") {
        m_statusLabel->setStyleSheet("color: #F39C12;");  // 橙色
    } else if (type == "error") {
        m_statusLabel->setStyleSheet("color: #E74C3C;");  // 红色
    } else {
        m_statusLabel->setStyleSheet("color: #ECF0F1;");  // 默认文字颜色
    }
}

void GameServerWidget::onFirstPageClicked()
{
    if (m_currentPage > 1) {
        m_currentPage = 1;
        onRefreshClicked();
    }
}

void GameServerWidget::onPrevPageClicked()
{
    if (m_currentPage > 1) {
        m_currentPage--;
        onRefreshClicked();
    }
}

void GameServerWidget::onNextPageClicked()
{
    if (m_currentPage < m_totalPages) {
        m_currentPage++;
        onRefreshClicked();
    }
}

void GameServerWidget::onLastPageClicked()
{
    if (m_currentPage < m_totalPages) {
        m_currentPage = m_totalPages;
        onRefreshClicked();
    }
}

void GameServerWidget::onPageSizeChanged()
{
    m_pageSize = m_pageSizeCombo->currentData().toInt();
    m_currentPage = 1; // 重置到第一页
    onRefreshClicked();
}

void GameServerWidget::onGameServersReceived(const QList<GameService::GameServer> &servers,
                                           const GameService::ServerSummary &summary)
{
    setUIEnabled(true);
    m_progressBar->setVisible(false);

    m_servers = servers;
    m_summary = summary;

    updateServerList(servers);
    updateServerSummary(summary);

    m_statusLabel->setText(QString("找到 %1 个服务器").arg(servers.size()));
    m_statusLabel->setStyleSheet(QString("color: %1;").arg(m_successColor));
}

void GameServerWidget::onGameJoinSucceeded(const GameService::GameLoginResult &result)
{
    setUIEnabled(true);
    m_progressBar->setVisible(false);

    // 根据游戏类型处理不同的连接方式
    if (result.serverInfo.gameType.toLower() == "snake") {
        // Snake游戏使用WebSocket连接
        handleSnakeGameConnection(result);
    } else {
        // 其他游戏使用传统方式
        handleGenericGameConnection(result);
    }
}

/**
 * @brief 处理Snake游戏的WebSocket连接
 * @param result 游戏认证结果
 *
 * 根据API文档，Snake游戏认证成功后的流程：
 * 1. Auth Service返回游戏令牌和WebSocket地址
 * 2. 客户端使用游戏令牌连接到Snake游戏服务的WebSocket
 * 3. 建立长连接后进入游戏大厅
 */
void GameServerWidget::handleSnakeGameConnection(const GameService::GameLoginResult &result)
{
    // 构建WebSocket URL（优先使用服务器提供的配置）
    QString websocketUrl;

    // 优先级1：直接使用服务器提供的WebSocket URL
    if (result.gameConfig.contains("websocket_url")) {
        websocketUrl = result.gameConfig["websocket_url"].toString();
        qDebug() << "GameServerWidget: 使用服务器提供的WebSocket URL:" << websocketUrl;
    }
    // 优先级2：使用服务器提供的WebSocket端口
    else if (result.gameConfig.contains("websocket_port")) {
        int wsPort = result.gameConfig["websocket_port"].toInt();
        if (wsPort > 0) {
            websocketUrl = QString("ws://%1:%2").arg(result.serverInfo.host).arg(wsPort);
            qDebug() << "GameServerWidget: 使用服务器提供的WebSocket端口:" << wsPort;
        }
    }
    // 优先级3：使用默认计算（避免硬编码）
    else {
        int websocketPort = (result.serverInfo.port == 8084) ? 8085 : result.serverInfo.port + 1;
        websocketUrl = QString("ws://%1:%2").arg(result.serverInfo.host).arg(websocketPort);
        qDebug() << "GameServerWidget: 使用计算的WebSocket端口:" << websocketPort;
    }

    QString message = QString("🐍 Snake游戏认证成功！\n\n"
                             "🎯 认证信息：\n"
                             "• 服务器：%1\n"
                             "• 玩家ID：%2\n"
                             "• 会话ID：%3\n"
                             "• 游戏令牌：%4...\n"
                             "• 会话有效期：%5 秒\n\n"
                             "🌐 连接信息：\n"
                             "• WebSocket地址：%6\n"
                             "• 服务器地区：%7\n"
                             "• 协议版本：qt6-optimized\n\n"
                             "🎮 即将建立WebSocket长连接并进入游戏大厅...")
                      .arg(result.serverInfo.name)
                      .arg(result.gameConfig.value("player_id").toString("未知"))
                      .arg(result.sessionId)
                      .arg(result.sessionToken.left(16))  // 只显示前16个字符
                      .arg(result.expiresIn)
                      .arg(websocketUrl)
                      .arg(result.serverInfo.region.toUpper());

    // 删除认证成功提示框，直接进行后续流程
    qDebug() << "GameServerWidget: Snake game authentication successful, proceeding without dialog";

    // 更新状态显示
    updateStatusMessage("🐍 正在建立Snake游戏WebSocket连接...", "info");

    qDebug() << "GameServerWidget: Snake game authentication successful";
    qDebug() << "GameServerWidget: WebSocket URL:" << websocketUrl;
    qDebug() << "GameServerWidget: Game token:" << result.sessionToken.left(20) << "...";

    // 构建WebSocket连接配置
    QJsonObject connectionConfig;
    connectionConfig["websocket_url"] = websocketUrl;
    connectionConfig["game_token"] = result.sessionToken;
    connectionConfig["player_id"] = result.gameConfig.value("player_id").toString("");
    connectionConfig["session_id"] = result.sessionId;
    connectionConfig["server_info"] = QJsonObject{
        {"server_id", result.serverInfo.serverId},
        {"host", result.serverInfo.host},
        {"port", result.serverInfo.port},
        {"region", result.serverInfo.region}
    };
    connectionConfig["game_config"] = result.gameConfig;

    // 发出信号，通知主窗口切换到Snake游戏界面并建立WebSocket连接
    emit snakeGameConnectionReady(result);

    // 最终状态更新
    updateStatusMessage("🐍 Snake游戏连接就绪，正在进入游戏大厅...", "success");
}

/**
 * @brief 处理通用游戏连接
 * @param result 游戏认证结果
 */
void GameServerWidget::handleGenericGameConnection(const GameService::GameLoginResult &result)
{
    QString message = QString("成功连接到服务器!\n\n"
                             "服务器: %1\n"
                             "会话ID: %2\n"
                             "服务器地址: %3:%4\n"
                             "会话过期时间: %5 秒")
                      .arg(result.serverInfo.name)
                      .arg(result.sessionId)
                      .arg(result.serverInfo.host)
                      .arg(result.serverInfo.port)
                      .arg(result.expiresIn);

    // 删除连接成功提示框，直接进行后续流程
    qDebug() << "GameServerWidget: Generic game connection successful, proceeding without dialog";

    updateStatusMessage("游戏连接成功", "success");

    // 可以在这里启动游戏客户端或跳转到游戏界面
    QString gameUrl = QString("game://%1:%2?token=%3&session=%4")
                      .arg(result.serverInfo.host)
                      .arg(result.serverInfo.port)
                      .arg(result.sessionToken)
                      .arg(result.sessionId);

    // 尝试打开游戏客户端
    if (!QDesktopServices::openUrl(QUrl(gameUrl))) {
        QMessageBox::information(this, "提示",
            QString("请手动启动游戏客户端并连接到:\n%1:%2")
            .arg(result.serverInfo.host)
            .arg(result.serverInfo.port));
    }
}

void GameServerWidget::onGameJoinFailed(const QString &error)
{
    setUIEnabled(true);
    m_progressBar->setVisible(false);

    // 根据选中的游戏类型显示不同的错误信息
    QString gameTypeIcon = "🎮";
    QString gameTypeName = "游戏";

    if (!m_selectedServer.serverId.isEmpty()) {
        if (m_selectedServer.gameType.toLower() == "snake") {
            gameTypeIcon = "🐍";
            gameTypeName = "Snake游戏";
        } else if (m_selectedServer.gameType.toLower() == "tetris") {
            gameTypeIcon = "🧩";
            gameTypeName = "俄罗斯方块";
        } else if (m_selectedServer.gameType.toLower() == "puzzle") {
            gameTypeIcon = "🧠";
            gameTypeName = "益智游戏";
        }
    }

    updateStatusMessage(QString("%1 %2连接失败: %3").arg(gameTypeIcon).arg(gameTypeName).arg(error), "error");

    // 构建详细的错误信息
    QString detailedError = QString("%1 %2连接失败\n\n"
                                   "❌ 错误信息：\n%3\n\n"
                                   "🔧 可能的解决方案：\n"
                                   "• 检查网络连接是否正常\n"
                                   "• 确认服务器状态是否在线\n"
                                   "• 尝试选择其他服务器\n"
                                   "• 刷新服务器列表后重试\n"
                                   "• 检查游戏客户端版本是否最新")
                           .arg(gameTypeIcon)
                           .arg(gameTypeName)
                           .arg(error);

    // 显示错误对话框
    QMessageBox msgBox(this);
    msgBox.setWindowTitle(QString("%1 连接失败").arg(gameTypeIcon));
    msgBox.setText(detailedError);
    msgBox.setIcon(QMessageBox::Warning);
    msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Retry);
    msgBox.setDefaultButton(QMessageBox::Retry);

    // 设置错误消息框样式
    msgBox.setStyleSheet(QString(
        "QMessageBox { background-color: %1; color: %2; }"
        "QMessageBox QPushButton { "
        "  background-color: %3; color: white; "
        "  border: none; border-radius: 6px; "
        "  padding: 8px 16px; font-weight: bold; "
        "}"
        "QMessageBox QPushButton:hover { background-color: %4; }"
    ).arg(m_backgroundColor).arg(m_textColor).arg(m_errorColor).arg("#C0392B"));

    QMessageBox::StandardButton reply = static_cast<QMessageBox::StandardButton>(msgBox.exec());

    // 如果用户选择重试，重新尝试连接
    if (reply == QMessageBox::Retry && !m_selectedServer.serverId.isEmpty()) {
        qDebug() << "GameServerWidget: User chose to retry connection";

        // 延迟1秒后重试，给用户一些反应时间
        QTimer::singleShot(1000, this, [this]() {
            updateStatusMessage("正在重试连接...", "info");
            onJoinClicked();
        });
    }
}

void GameServerWidget::onRequestFailed(const QString &error)
{
    setUIEnabled(true);
    m_progressBar->setVisible(false);
    m_statusLabel->setText("请求失败: " + error);
    m_statusLabel->setStyleSheet(QString("color: %1;").arg(m_errorColor));
}

void GameServerWidget::onAutoRefreshTimer()
{
    if (m_autoRefreshEnabled && m_refreshButton->isEnabled()) {
        onRefreshClicked();
    }
}

void GameServerWidget::onServerSelectionChanged()
{
    bool hasSelection = m_serverTable->currentRow() >= 0;
    m_joinButton->setEnabled(hasSelection);

    if (hasSelection) {
        GameService::GameServer server = getSelectedServer();
        updateServerDetails(server);
    } else {
        m_serverDetailsText->setText("请选择一个服务器查看详细信息");
    }
}

void GameServerWidget::updateServerList(const QList<GameService::GameServer> &servers)
{
    m_serverTable->setRowCount(servers.size());

    for (int i = 0; i < servers.size(); ++i) {
        const GameService::GameServer &server = servers[i];

        // 服务器名称 - 为Snake游戏服务器添加特殊前缀
        QString serverName = server.name;
        if (server.gameType.toLower() == "snake") {
            if (!serverName.startsWith("🐍")) {
                serverName = "🐍 " + serverName;
            }
        }

        QTableWidgetItem *nameItem = new QTableWidgetItem(serverName);
        nameItem->setToolTip(QString("%1\n服务器ID: %2\n主机: %3:%4")
                            .arg(server.name)
                            .arg(server.serverId)
                            .arg(server.host)
                            .arg(server.port));

        // 为Snake游戏服务器设置特殊样式
        if (server.gameType.toLower() == "snake") {
            nameItem->setFont(QFont(nameItem->font().family(), nameItem->font().pointSize(), QFont::Bold));
        }

        m_serverTable->setItem(i, 0, nameItem);

        // 游戏类型 - 为Snake游戏添加特殊图标
        QString gameTypeText = server.gameType;
        if (server.gameType.toLower() == "snake") {
            gameTypeText = "🐍 " + server.gameType.toUpper();
        } else if (server.gameType.toLower() == "tetris") {
            gameTypeText = "🧩 " + server.gameType.toUpper();
        } else if (server.gameType.toLower() == "puzzle") {
            gameTypeText = "🧠 " + server.gameType.toUpper();
        } else {
            gameTypeText = "🎮 " + server.gameType.toUpper();
        }

        QTableWidgetItem *gameTypeItem = new QTableWidgetItem(gameTypeText);

        // 为Snake游戏服务器设置特殊颜色
        if (server.gameType.toLower() == "snake") {
            gameTypeItem->setForeground(QColor("#7ED321")); // 绿色，突出Snake游戏
            gameTypeItem->setFont(QFont(gameTypeItem->font().family(), gameTypeItem->font().pointSize(), QFont::Bold));
        }

        m_serverTable->setItem(i, 1, gameTypeItem);

        // 地区
        QTableWidgetItem *regionItem = new QTableWidgetItem(server.region);
        m_serverTable->setItem(i, 2, regionItem);

        // 延迟
        QString pingText = (server.ping >= 0) ? QString("%1ms").arg(server.ping) : "未知";
        QTableWidgetItem *pingItem = new QTableWidgetItem(pingText);
        pingItem->setData(Qt::UserRole, server.ping); // 用于排序
        if (server.ping >= 0 && server.ping < 50) {
            pingItem->setForeground(QColor(m_successColor));
        } else if (server.ping < 100) {
            pingItem->setForeground(QColor(m_warningColor));
        } else {
            pingItem->setForeground(QColor(m_errorColor));
        }
        m_serverTable->setItem(i, 3, pingItem);

        // 玩家数
        QTableWidgetItem *playersItem = new QTableWidgetItem(formatPlayerCount(server.currentPlayers, server.maxPlayers));
        playersItem->setData(Qt::UserRole, server.currentPlayers); // 用于排序
        double playerRatio = (double)server.currentPlayers / server.maxPlayers;
        if (playerRatio < 0.7) {
            playersItem->setForeground(QColor(m_successColor));
        } else if (playerRatio < 0.9) {
            playersItem->setForeground(QColor(m_warningColor));
        } else {
            playersItem->setForeground(QColor(m_errorColor));
        }
        m_serverTable->setItem(i, 4, playersItem);

        // 负载
        QTableWidgetItem *loadItem = new QTableWidgetItem(formatLoadPercentage(server.loadPercentage));
        loadItem->setData(Qt::UserRole, server.loadPercentage); // 用于排序
        if (server.loadPercentage < 60) {
            loadItem->setForeground(QColor(m_successColor));
        } else if (server.loadPercentage < 80) {
            loadItem->setForeground(QColor(m_warningColor));
        } else {
            loadItem->setForeground(QColor(m_errorColor));
        }
        m_serverTable->setItem(i, 5, loadItem);

        // 状态
        QTableWidgetItem *statusItem = new QTableWidgetItem(getServerStatusText(server.status));
        statusItem->setForeground(getServerStatusColor(server.status));
        m_serverTable->setItem(i, 6, statusItem);

        // 版本
        QTableWidgetItem *versionItem = new QTableWidgetItem(server.version);
        m_serverTable->setItem(i, 7, versionItem);
    }

    m_serverTable->resizeColumnsToContents();
}

/**
 * @brief 更新服务器汇总统计信息
 * @param summary 服务器汇总统计数据
 *
 * 更新UI中显示的服务器统计信息，包括文本内容、分页控制和状态颜色。
 */
void GameServerWidget::updateServerSummary(const GameService::ServerSummary &summary)
{
    // === 获取当前游戏类型对应的图标 ===
    QString selectedGameType = m_gameTypeCombo->currentData().toString();
    QString gameIcon = selectedGameType == "snake" ? "🐍" : 
                      selectedGameType == "tetris" ? "🧩" : 
                      selectedGameType == "puzzle" ? "🧠" : "🎮";

    // === 更新统计文本 ===
    /* 字符串格式化示例：
     * 输入数据：
     * summary.totalServers = 150
     * summary.onlineServers = 120
     * summary.totalPlayers = 2500
     * summary.totalCapacity = 15000
     *
     * 格式化结果：
     * "🐍 总服务器: 150"
     * "🐍 在线服务器: 120"
     * "🐍 总玩家数: 2500 / 15000"
     *
     * QString::arg()方法说明：
     * - %1, %2, %3... 是占位符
     * - .arg()按顺序替换占位符
     * - 支持多个参数的链式调用
     */
    m_totalServersLabel->setText(QString("%1 总服务器: %2").arg(gameIcon).arg(summary.totalServers));
    m_onlineServersLabel->setText(QString("%1 在线服务器: %2").arg(gameIcon).arg(summary.onlineServers));
    m_totalPlayersLabel->setText(QString("%1 总玩家: %2 / %3")
                                .arg(gameIcon)
                                .arg(summary.totalPlayers)
                                .arg(summary.totalCapacity));

    // === 更新分页信息 ===
    /* 分页数据更新：
     * summary.totalPages = 3    → m_totalPages = 3
     * summary.currentPage = 1   → m_currentPage = 1
     * summary.pageSize = 50     → m_pageSize = 50
     */
    m_totalPages = summary.totalPages;
    m_currentPage = summary.currentPage;
    m_pageSize = summary.pageSize;

    updatePaginationControls();     // 更新分页控件状态

    // === 动态颜色更新 ===
    /* 根据在线服务器比例设置颜色：
     * 条件判断：
     * 1. onlineServers == 0：全部离线 → 红色（错误色）
     * 2. onlineServers < totalServers * 0.8：低于80% → 橙色（警告色）
     * 3. 其他情况：正常状态 → 绿色（成功色）
     *
     * 颜色值示例：
     * m_errorColor = "#E74C3C"（红色）
     * m_warningColor = "#F39C12"（橙色）
     * m_successColor = "#27AE60"（绿色）
     *
     * 生成的CSS样式：
     * "color: #E74C3C;" 或 "color: #F39C12;" 或 "color: #27AE60;"
     */
    if (summary.onlineServers == 0) {
        // 全部服务器离线 - 红色警告
        m_onlineServersLabel->setStyleSheet(QString("color: %1;").arg(m_errorColor));
    } else if (summary.onlineServers < summary.totalServers * 0.8) {
        // 在线服务器不足80% - 橙色警告
        m_onlineServersLabel->setStyleSheet(QString("color: %1;").arg(m_warningColor));
    } else {
        // 在线服务器充足 - 绿色正常
        m_onlineServersLabel->setStyleSheet(QString("color: %1;").arg(m_successColor));
    }
}

/**
 * @brief 更新分页控制组件状态
 *
 * 根据当前分页信息更新分页控件的显示文本和按钮状态。
 */
void GameServerWidget::updatePaginationControls()
{
    // === 更新页面信息标签 ===
    /* 页面信息字符串格式化：
     * 输入数据：
     * m_currentPage = 2
     * m_totalPages = 5
     *
     * 格式化结果：
     * "第 2 页，共 5 页"
     *
     * 这为用户提供了清晰的分页位置信息
     */
    m_pageInfoLabel->setText(QString("第 %1 页，共 %2 页")
                            .arg(m_currentPage)
                            .arg(m_totalPages));

    // === 更新分页按钮状态 ===
    /* 按钮启用/禁用逻辑：
     *
     * 首页和上一页按钮：
     * - 当前页 > 1 时启用
     * - 当前页 = 1 时禁用（已在第一页）
     *
     * 下一页和末页按钮：
     * - 当前页 < 总页数 时启用
     * - 当前页 = 总页数 时禁用（已在最后一页）
     *
     * 示例：当前页=1，总页数=5
     * - 首页按钮：禁用（已在首页）
     * - 上一页按钮：禁用（已在首页）
     * - 下一页按钮：启用（可以到第2页）
     * - 末页按钮：启用（可以到第5页）
     */
    m_firstPageButton->setEnabled(m_currentPage > 1);          // 首页按钮
    m_prevPageButton->setEnabled(m_currentPage > 1);           // 上一页按钮
    m_nextPageButton->setEnabled(m_currentPage < m_totalPages); // 下一页按钮
    m_lastPageButton->setEnabled(m_currentPage < m_totalPages); // 末页按钮

    // === 更新页面大小下拉框 ===
    /* 页面大小同步：
     * 1. 在下拉框中查找与当前页面大小匹配的选项
     * 2. findData()方法查找数据值匹配的索引
     * 3. 如果找到匹配项，设置为当前选中项
     *
     * 页面大小选项通常包括：
     * - "20 条/页" → 数据值：20
     * - "50 条/页" → 数据值：50
     * - "100 条/页" → 数据值：100
     */
    int currentIndex = m_pageSizeCombo->findData(m_pageSize);
    if (currentIndex >= 0) {
        m_pageSizeCombo->setCurrentIndex(currentIndex);
    }
}

/**
 * @brief 更新服务器详细信息显示
 * @param server 游戏服务器信息结构体
 *
 * 将服务器信息格式化为HTML并显示在详情面板中。
 * 包含丰富的格式化和字符串处理示例。
 */
void GameServerWidget::updateServerDetails(const GameService::GameServer &server)
{
    /* HTML字符串构建和格式化示例：
     *
     * 输入服务器数据：
     * server.name = "Snake Asia Server 1"
     * server.serverId = "snake-asia-01"
     * server.gameType = "snake"
     * server.region = "asia"
     * server.host = "snake-asia-01.gameserver.com"
     * server.port = 8080
     * server.status = "online"
     * server.ping = 25
     * server.currentPlayers = 45
     * server.maxPlayers = 100
     * server.loadPercentage = 45.5
     * server.version = "1.2.3"
     * server.features = ["ranked", "casual", "tournament"]
     * server.lastUpdated = "2024-01-01T12:00:00Z"
     *
     * HTML模板说明：
     * - %1, %2, %3... 是占位符，按顺序被.arg()方法替换
     * - <h3>, <p>, <b>, <span> 是HTML标签，用于格式化显示
     * - style='color: %7;' 动态设置颜色样式
     *
     * 格式化后的HTML示例：
     * <h3>Snake Asia Server 1</h3>
     * <p><b>服务器ID:</b> snake-asia-01</p>
     * <p><b>游戏类型:</b> snake</p>
     * <p><b>地区:</b> asia</p>
     * <p><b>服务器地址:</b> snake-asia-01.gameserver.com:8080</p>
     * <p><b>状态:</b> <span style='color: #27AE60;'>在线</span></p>
     * <p><b>延迟:</b> 25ms</p>
     * <p><b>玩家数:</b> 45 / 100</p>
     * <p><b>负载:</b> 45.5%</p>
     * <p><b>版本:</b> 1.2.3</p>
     * <p><b>功能:</b> ranked, casual, tournament</p>
     * <p><b>最后更新:</b> 2024-01-01T12:00:00Z</p>
     */
    QString details = QString(
        "<h3>%1</h3>"                                           // %1: 服务器名称
        "<p><b>服务器ID:</b> %2</p>"                             // %2: 服务器ID
        "<p><b>游戏类型:</b> %3</p>"                             // %3: 游戏类型
        "<p><b>地区:</b> %4</p>"                                // %4: 服务器地区
        "<p><b>服务器地址:</b> %5:%6</p>"                        // %5: 主机地址, %6: 端口
        "<p><b>状态:</b> <span style='color: %7;'>%8</span></p>" // %7: 状态颜色, %8: 状态文本
        "<p><b>延迟:</b> %9</p>"                                // %9: 延迟时间
        "<p><b>玩家数:</b> %10 / %11</p>"                       // %10: 当前玩家, %11: 最大玩家
        "<p><b>负载:</b> %12%</p>"                              // %12: 负载百分比
        "<p><b>版本:</b> %13</p>"                               // %13: 服务器版本
        "<p><b>功能:</b> %14</p>"                               // %14: 功能列表
        "<p><b>最后更新:</b> %15</p>"                           // %15: 最后更新时间
    )
    // === 链式.arg()调用进行参数替换 ===
    .arg(server.name)                                           // %1 → "Snake Asia Server 1"
    .arg(server.serverId)                                       // %2 → "snake-asia-01"
    .arg(server.gameType)                                       // %3 → "snake"
    .arg(server.region)                                         // %4 → "asia"
    .arg(server.host)                                           // %5 → "snake-asia-01.gameserver.com"
    .arg(server.port)                                           // %6 → 8080
    .arg(getServerStatusColor(server.status).name())            // %7 → "#27AE60"（颜色十六进制值）
    .arg(getServerStatusText(server.status))                    // %8 → "在线"（本地化状态文本）
    .arg(server.ping >= 0 ? QString("%1ms").arg(server.ping) : "未知")  // %9 → "25ms" 或 "未知"
    .arg(server.currentPlayers)                                 // %10 → 45
    .arg(server.maxPlayers)                                     // %11 → 100
    .arg(server.loadPercentage, 0, 'f', 1)                     // %12 → "45.5"（保留1位小数）
    .arg(server.version)                                        // %13 → "1.2.3"
    .arg(server.features.join(", "))                           // %14 → "ranked, casual, tournament"（数组连接）
    .arg(server.lastUpdated);                                  // %15 → "2024-01-01T12:00:00Z"

    // === 设置HTML内容到文本显示组件 ===
    m_serverDetailsText->setHtml(details);
}

void GameServerWidget::setUIEnabled(bool enabled)
{
    m_gameTypeCombo->setEnabled(enabled);
    m_statusCombo->setEnabled(enabled);
    m_healthyOnlyCombo->setEnabled(enabled);
    m_sortByCombo->setEnabled(enabled);
    m_refreshButton->setEnabled(enabled);
    m_autoRefreshButton->setEnabled(enabled);
    m_joinButton->setEnabled(enabled && m_serverTable->currentRow() >= 0);
    m_serverTable->setEnabled(enabled);
}

GameService::GameServer GameServerWidget::getSelectedServer() const
{
    int row = m_serverTable->currentRow();
    if (row >= 0 && row < m_servers.size()) {
        return m_servers[row];
    }
    return GameService::GameServer{};
}

/**
 * @brief 获取服务器状态的本地化文本
 * @param status 服务器状态字符串（来自API响应）
 * @return 本地化的状态显示文本
 *
 * 将英文的服务器状态转换为用户友好的中文显示文本。
 */
QString GameServerWidget::getServerStatusText(const QString &status)
{
    /* 状态字符串映射示例：
     * 输入（API返回的英文状态） → 输出（用户看到的中文文本）
     *
     * "online" → "在线"
     * - 服务器正常运行，可以连接和游戏
     *
     * "maintenance" → "维护"
     * - 服务器正在维护，暂时不可用
     *
     * 其他任何值 → "未知"
     * - 包括 "offline"、空字符串、无效值等
     * - 提供默认的安全显示文本
     *
     * 使用场景：
     * - 服务器列表表格中的状态列
     * - 服务器详情面板中的状态显示
     * - 工具提示和状态栏信息
     */
    if (status == "online") {
        return "在线";          // 绿色显示，表示可用
    } else if (status == "maintenance") {
        return "维护";          // 橙色显示，表示维护中
    } else {
        return "未知";          // 红色显示，表示不可用或未知状态
    }
}

/**
 * @brief 获取服务器状态对应的颜色
 * @param status 服务器状态字符串（来自API响应）
 * @return 状态对应的QColor颜色对象
 *
 * 根据服务器状态返回相应的颜色，用于UI中的状态指示。
 */
QColor GameServerWidget::getServerStatusColor(const QString &status)
{
    /* 状态颜色映射示例：
     * 输入状态 → 输出颜色（十六进制值）
     *
     * "online" → QColor("#27AE60")（绿色）
     * - 表示服务器健康、可用
     * - 用户可以安全连接
     *
     * "maintenance" → QColor("#F39C12")（橙色）
     * - 表示服务器维护中
     * - 提醒用户暂时不可用
     *
     * 其他状态 → QColor("#E74C3C")（红色）
     * - 表示服务器离线或异常
     * - 警告用户不可连接
     *
     * 颜色值来源：
     * - m_successColor = "#27AE60"（成功色）
     * - m_warningColor = "#F39C12"（警告色）
     * - m_errorColor = "#E74C3C"（错误色）
     *
     * 使用场景：
     * - 表格中状态文本的前景色
     * - 详情面板中状态文本的颜色
     * - 状态指示器的背景色
     */
    if (status == "online") {
        return QColor(m_successColor);      // 绿色：#27AE60
    } else if (status == "maintenance") {
        return QColor(m_warningColor);      // 橙色：#F39C12
    } else {
        return QColor(m_errorColor);        // 红色：#E74C3C
    }
}

/**
 * @brief 格式化玩家数量显示
 * @param current 当前在线玩家数
 * @param max 最大玩家容量
 * @return 格式化的玩家数量字符串
 *
 * 将玩家数量格式化为 "当前/最大" 的显示格式。
 */
QString GameServerWidget::formatPlayerCount(int current, int max)
{
    /* 玩家数量格式化示例：
     * 输入数据：
     * current = 45（当前在线玩家）
     * max = 100（服务器最大容量）
     *
     * 格式化过程：
     * QString("%1/%2") → 模板字符串，包含两个占位符
     * .arg(current) → 替换%1为45
     * .arg(max) → 替换%2为100
     *
     * 输出结果：
     * "45/100"
     *
     * 其他示例：
     * current=0, max=50 → "0/50"（空服务器）
     * current=25, max=25 → "25/25"（满员服务器）
     * current=8, max=10 → "8/10"（接近满员）
     *
     * 用途：
     * - 服务器列表表格中的玩家数列
     * - 服务器详情面板中的玩家信息
     * - 工具提示中的快速信息显示
     */
    return QString("%1/%2").arg(current).arg(max);
}

/**
 * @brief 格式化负载百分比显示
 * @param load 服务器负载百分比（0.0-100.0）
 * @return 格式化的负载百分比字符串
 *
 * 将负载百分比格式化为带百分号的字符串，保留一位小数。
 */
QString GameServerWidget::formatLoadPercentage(double load)
{
    /* 负载百分比格式化示例：
     * 输入数据：
     * load = 45.678（服务器负载百分比）
     *
     * 格式化过程：
     * QString("%1%") → 模板字符串，包含一个占位符和百分号
     * .arg(load, 0, 'f', 1) → 格式化参数说明：
     *   - load: 要格式化的数值
     *   - 0: 字段宽度（0表示自动调整）
     *   - 'f': 格式类型（'f'表示固定小数点格式）
     *   - 1: 小数位数（保留1位小数）
     *
     * 输出结果：
     * "45.7%"
     *
     * 其他示例：
     * load=0.0 → "0.0%"（无负载）
     * load=67.234 → "67.2%"（中等负载）
     * load=95.678 → "95.7%"（高负载）
     * load=100.0 → "100.0%"（满负载）
     *
     * 负载含义：
     * - 0-60%：绿色显示，负载较低，性能良好
     * - 60-80%：橙色显示，负载中等，可能影响性能
     * - 80-100%：红色显示，负载较高，可能出现延迟
     *
     * 用途：
     * - 服务器列表表格中的负载列
     * - 服务器详情面板中的负载信息
     * - 性能监控和服务器选择参考
     */
    return QString("%1%").arg(load, 0, 'f', 1);
}

void GameServerWidget::applyStyles()
{
    // 分解长CSS字符串以避免编译器限制
    QString baseStyles = QString(R"(
        GameServerWidget {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 %1, stop:0.5 #34495E, stop:1 #2C3E50);
            color: %2;
            font-family: 'Microsoft YaHei', 'Segoe UI', Arial, sans-serif;
        }

        QWidget {
            background-color: transparent; /* 确保子组件使用透明背景，继承父容器背景 */
            color: %2;
            font-family: 'Microsoft YaHei', 'Segoe UI', Arial, sans-serif;
        }

        /* 页面头部样式 */
        #pageHeader {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 %1, stop:0.5 #34495E, stop:1 #2C3E50);
            border-radius: 12px;
            margin: 4px; /* 统一外边距 */
            border: 1px solid rgba(74, 144, 226, 0.3);
        }

        #pageTitle {
            color: %3;
            font-size: 28px;
            font-weight: bold;
            margin: 0;
            /* 移除不支持的text-shadow属性 */
        }

        #pageSubtitle {
            color: #BDC3C7;
            font-size: 15px;
            font-weight: 400;
            margin: 0;
            /* 移除不支持的text-shadow属性 */
        }

        #quickActionBtn {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(74, 144, 226, 0.8), stop:1 rgba(52, 152, 219, 0.8));
            color: white;
            border: none;
            border-radius: 10px;
            padding: 10px 20px;
            font-size: 14px;
            font-weight: 600;
            min-height: 20px;
        }

        #quickActionBtn:hover {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(93, 173, 226, 0.9), stop:1 rgba(74, 144, 226, 0.9));
            /* 移除不支持的box-shadow和transform属性 */
        }

        #mainSplitter::handle {
            background: rgba(74, 144, 226, 0.4);
            width: 3px; /* 更细的分割线 */
            border-radius: 1px;
            margin: 4px 0; /* 与容器边距对齐 */
        }

        #mainSplitter::handle:hover {
            background: rgba(74, 144, 226, 0.7);
            width: 4px;
        }

        /* 现代化筛选器卡片 */
        #modernFilterCard {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 %1, stop:0.5 #34495E, stop:1 #2C3E50);
            border: 1px solid rgba(74, 144, 226, 0.5);
            border-radius: 12px;
            margin: 4px; /* 统一外边距 */
            /* 移除不支持的box-shadow属性 */
        }

        #modernFilterCard:hover {
            border-color: rgba(74, 144, 226, 0.7);
            /* 移除不支持的box-shadow属性 */
        }

        #filterTitle {
            color: %3;
            font-size: 16px;
            font-weight: bold;
            /* 移除不支持的text-shadow属性 */
        }

        #filterSeparator {
            background: rgba(74, 144, 226, 0.4);
            margin: 0 10px;
        }

        /* 现代化无边框容器 - 与外围背景一致 */
        #modernServerListWidget, #modernDetailsWidget, #modernStatusWidget {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 %1, stop:0.5 #34495E, stop:1 #2C3E50);
            border: 1px solid rgba(74, 144, 226, 0.3);
            border-radius: 12px;
            margin: 4px; /* 统一外边距 */
        }

        #modernPaginationWidget {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                stop:0 %1, stop:0.5 #34495E, stop:1 #2C3E50);
            border: 1px solid rgba(74, 144, 226, 0.4);
            border-radius: 10px;
            margin: 4px; /* 统一外边距 */
        }

        #modernServerListWidget:hover, #modernDetailsWidget:hover {
            border-color: rgba(74, 144, 226, 0.5);
            /* 移除不支持的box-shadow属性 */
        }

        #filterGroup::title, #serverListGroup::title, #detailsGroup::title, #statusGroup::title, #paginationGroup::title {
            color: %3;
            font-size: 16px;
            font-weight: bold;
            padding: 0 15px;
            /* 移除不支持的text-shadow属性 */
        }

        #filterLabel {
            color: %2;
            font-size: 13px;
            font-weight: 600;
            margin-bottom: 5px;
            text-align: center;
            /* 移除不支持的text-shadow属性 */
        }

        /* 现代化筛选器下拉框 */
        #modernFilterCombo {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.95), stop:1 rgba(52, 73, 94, 0.95));
            border: 2px solid rgba(74, 144, 226, 0.4);
            border-radius: 10px;
            padding: 8px 12px;
            font-size: 13px;
            color: %2;
            font-weight: 500;
            min-height: 20px;
        }

        #modernFilterCombo:focus {
            border-color: %3;
            /* 移除不支持的box-shadow属性 */
        }

        #modernFilterCombo:hover {
            border-color: rgba(74, 144, 226, 0.6);
            /* 移除不支持的box-shadow和transform属性 */
        }

        #modernFilterCombo::drop-down {
            border: none;
            background-color: transparent;
            width: 20px;
        }

        #modernFilterCombo::down-arrow {
            image: none;
            border-left: 5px solid transparent;
            border-right: 5px solid transparent;
            border-top: 5px solid %2;
            margin-right: 8px;
        }

        #modernFilterCombo QAbstractItemView {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.98), stop:1 rgba(52, 73, 94, 0.98));
            border: 2px solid %3;
            border-radius: 10px;
            color: %2;
            selection-background-color: %3;
            outline: none;
        }

        #modernFilterCombo QAbstractItemView::item {
            padding: 10px 15px;
            border-bottom: 1px solid rgba(74, 144, 226, 0.2);
        }

        #modernFilterCombo QAbstractItemView::item:hover {
            background-color: rgba(74, 144, 226, 0.3);
        }

        /* 现代化分页控件样式 */
        #modernPaginationWidget {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(255, 255, 255, 0.08), stop:1 rgba(255, 255, 255, 0.04));
            border: 1px solid rgba(74, 144, 226, 0.4);
            border-radius: 10px;
            margin: 5px 0;
        }

        #paginationLabel {
            color: %2;
            font-size: 13px;
            font-weight: 600;
            /* 移除不支持的text-shadow属性 */
        }

        #modernPaginationCombo {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.9), stop:1 rgba(52, 73, 94, 0.9));
            border: 2px solid rgba(74, 144, 226, 0.4);
            border-radius: 8px;
            padding: 6px 10px;
            font-size: 12px;
            color: %2;
            font-weight: 500;
            min-width: 60px;
        }

        #modernPaginationCombo:hover {
            border-color: rgba(74, 144, 226, 0.6);
            /* 移除不支持的box-shadow属性 */
        }

        #paginationButton {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.9), stop:1 rgba(52, 73, 94, 0.9));
            color: %2;
            border: 2px solid #34495E;
            border-radius: 8px;
            padding: 10px 18px;
            font-size: 13px;
            font-weight: bold;
            min-width: 70px;
        }

        #paginationButton:hover {
            border-color: %3;
            color: %3;
        }

        #paginationButton:pressed {
            background-color: rgba(74, 144, 226, 0.2);
        }

        #paginationButton:disabled {
            background-color: #7F8C8D;
            color: #BDC3C7;
            border-color: #7F8C8D;
        }

        #pageInfoLabel {
            color: %3;
            font-size: 14px;
            font-weight: bold;
            background-color: rgba(44, 62, 80, 0.6);
            border: 1px solid #34495E;
            border-radius: 4px;
            padding: 8px 12px;
        }

    )").arg(m_backgroundColor, m_textColor, m_primaryColor);

    QString filterStyles = QString(R"(
        #filterCombo {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.95), stop:1 rgba(52, 73, 94, 0.95));
            border: 2px solid #34495E;
            border-radius: 8px;
            padding: 10px 15px;
            font-size: 13px;
            color: %2;
            font-weight: 500;
        }

        #filterCombo:focus {
            border-color: %3;
            /* 移除不支持的box-shadow属性 */
        }

        #filterCombo:hover {
            border-color: #5DADE2;
            /* 移除不支持的box-shadow属性 */
        }

        #filterCombo::drop-down {
            border: none;
            background-color: transparent;
            width: 20px;
        }

        #filterCombo::down-arrow {
            image: none;
            border-left: 6px solid transparent;
            border-right: 6px solid transparent;
            border-top: 6px solid %2;
            margin-right: 8px;
        }

        #filterCombo QAbstractItemView {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.98), stop:1 rgba(52, 73, 94, 0.98));
            border: 2px solid %3;
            border-radius: 8px;
            color: %2;
            selection-background-color: %3;
            outline: none;
        }

        #filterCombo QAbstractItemView::item {
            padding: 8px 12px;
            border-bottom: 1px solid rgba(74, 144, 226, 0.2);
        }

        #filterCombo QAbstractItemView::item:hover {
            background-color: rgba(74, 144, 226, 0.3);
        }

        #primaryButton {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 %3, stop:1 #3498DB);
            color: white;
            border: none;
            border-radius: 10px;
            padding: 12px 24px;
            font-size: 14px;
            font-weight: bold;
            /* 移除不支持的text-shadow属性 */
        }

        #primaryButton:hover {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 #5DADE2, stop:1 #4A90E2);
            /* 移除不支持的box-shadow和transform属性 */
        }

        #primaryButton:pressed {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 #3498DB, stop:1 #2980B9);
            /* 移除不支持的transform属性 */
        }

        #primaryButton:disabled {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 #7F8C8D, stop:1 #6C7B7D);
            color: #BDC3C7;
            /* 移除不支持的box-shadow属性 */
        }

        #toggleButton {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(44, 62, 80, 0.9), stop:1 rgba(52, 73, 94, 0.9));
            color: %2;
            border: 2px solid #34495E;
            border-radius: 8px;
            padding: 12px 18px;
            font-size: 13px;
            font-weight: 500;
        }

        #toggleButton:checked {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 %4, stop:1 #27AE60);
            color: white;
            border-color: %4;
        }

        #toggleButton:hover {
            border-color: %3;
            /* 移除不支持的box-shadow属性 */
        }

        #serverTable {
            background-color: rgba(44, 62, 80, 0.95);
            alternate-background-color: rgba(52, 73, 94, 0.8);
            gridline-color: rgba(74, 144, 226, 0.3);
            border: 2px solid rgba(74, 144, 226, 0.4);
            border-radius: 12px;
            color: %2;
            font-size: 14px;
            font-weight: 500;
            selection-background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop:0 rgba(74, 144, 226, 0.8), stop:1 rgba(93, 173, 226, 0.8));
            padding: 2px;
        }

        /* 确保表格的所有子组件都有正确的背景 */
        #serverTable QHeaderView::section {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                stop:0 rgba(74, 144, 226, 0.7), stop:1 rgba(52, 73, 94, 0.9));
            color: %2;
            border: 1px solid rgba(74, 144, 226, 0.4);
            border-radius: 6px;
            padding: 12px 8px;
            font-size: 13px;
            font-weight: bold;
            margin: 1px;
        }

        #serverTable QScrollBar:vertical {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop:0 rgba(44, 62, 80, 0.8), stop:1 rgba(52, 73, 94, 0.8));
            width: 14px;
            border-radius: 7px;
            border: 1px solid rgba(74, 144, 226, 0.3);
            margin: 2px;
        }

        #serverTable QScrollBar::handle:vertical {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop:0 rgba(74, 144, 226, 0.8), stop:1 rgba(93, 173, 226, 0.8));
            border-radius: 6px;
            min-height: 25px;
            border: 1px solid rgba(74, 144, 226, 0.4);
        }

        #serverTable QScrollBar::handle:vertical:hover {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop:0 rgba(93, 173, 226, 0.9), stop:1 rgba(74, 144, 226, 0.9));
        }

        #serverTable QScrollBar::add-line:vertical, 
        #serverTable QScrollBar::sub-line:vertical {
            background: transparent;
            height: 0px;
        }

        #serverTable::item {
            padding: 12px 8px;
            border: none;
            border-radius: 4px;
            margin: 1px;
        }

        #serverTable::item:selected {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop:0 rgba(74, 144, 226, 0.9), stop:1 rgba(93, 173, 226, 0.9));
            color: white;
            font-weight: 600;
        }

        #serverTable::item:hover {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
                stop:0 rgba(74, 144, 226, 0.4), stop:1 rgba(93, 173, 226, 0.4));
            border: 1px solid rgba(74, 144, 226, 0.6);
        }

        #serverTable QHeaderView::section {
            background-color: rgba(52, 73, 94, 0.9);
            color: %2;
            border: 1px solid #34495E;
            padding: 10px 8px;
            font-weight: bold;
            font-size: 13px;
        }

        #serverTable QHeaderView::section:hover {
            background-color: %3;
            color: white;
        }

        #detailsText {
            background-color: rgba(44, 62, 80, 0.95);
            border: none; /* 去除边框，由容器提供 */
            border-radius: 6px;
            color: %2;
            font-size: 13px;
            padding: 10px;
        }

        /* 确保详情文本编辑器的滚动条也有正确的样式 */
        #detailsText QScrollBar:vertical {
            background-color: rgba(44, 62, 80, 0.8);
            width: 12px;
            border-radius: 6px;
        }

        #detailsText QScrollBar::handle:vertical {
            background-color: rgba(74, 144, 226, 0.6);
            border-radius: 6px;
            min-height: 20px;
        }

        #statLabel {
            color: %2;
            font-size: 13px;
            font-weight: 500;
            padding: 3px 0;
        }

        #statusLabel {
            font-size: 13px;
            padding: 8px;
            border-radius: 5px;
            margin: 5px 0;
        }

        #progressBar {
            border: 2px solid %3;
            border-radius: 5px;
            text-align: center;
            background-color: rgba(44, 62, 80, 0.9);
            font-size: 12px;
        }

        #progressBar::chunk {
            background-color: %3;
            border-radius: 3px;
        }

        #separator {
            color: #34495E;
            background-color: #34495E;
        }

        QSplitter::handle {
            background-color: #34495E;
            width: 3px;
        }

        QSplitter::handle:hover {
            background-color: %3;
        }

        QLabel {
            color: %2;
            font-size: 13px;
        }
    )").arg(m_backgroundColor, m_textColor, m_primaryColor);

    // 应用组合的样式
    setStyleSheet(baseStyles + filterStyles);
}

QWidget* GameServerWidget::createFilterWidget(const QString &label, const QString &objectName)
{
    QWidget *widget = new QWidget();
    widget->setObjectName(objectName + "Widget");

    QVBoxLayout *layout = new QVBoxLayout(widget);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(5);

    // 标签
    QLabel *labelWidget = new QLabel(label);
    labelWidget->setObjectName("filterLabel");
    labelWidget->setAlignment(Qt::AlignCenter);
    layout->addWidget(labelWidget);

    return widget;
}

// =================== 服务发现相关槽函数实现 ===================

// onDiscoveryModeChanged方法已删除，因为不再支持传统列表模式

/**
 * @brief 处理服务发现完成信号
 * @param services 发现的服务列表
 * @param gameType 查询的游戏类型
 * @param queryInfo 查询信息
 *
 * 处理服务发现API返回的服务列表，将服务信息转换为游戏服务器格式并显示
 */
void GameServerWidget::onGameServicesDiscovered(const QList<GameServiceInfo> &services, const QString &gameType, const QJsonObject &queryInfo)
{
    qDebug() << "GameServerWidget: 服务发现完成 - 服务数量:" << services.size() << "游戏类型:" << gameType;
    
    // === 详细的调试信息 ===
    for (int i = 0; i < services.size(); ++i) {
        const GameServiceInfo &service = services[i];
        qDebug() << QString("服务 %1: %2").arg(i+1).arg(service.serviceName);
        qDebug() << "  - 主机:" << service.host << "端口:" << service.port;
        qDebug() << "  - 健康状态:" << service.healthy;
        qDebug() << "  - 游戏类型:" << service.gameType();
        qDebug() << "  - 最大玩家:" << service.maxPlayers();
        qDebug() << "  - 地区:" << service.region();
        qDebug() << "  - 端点:" << service.endpoints.join(", ");
        qDebug() << "  - 权重:" << service.weight;
        qDebug() << "  - 元数据:" << service.metadata;
    }
    
    // 转换服务发现结果为GameServer格式
    QList<GameService::GameServer> gameServers;
    for (const GameServiceInfo &service : services) {
        GameService::GameServer server;
        
        // 基本信息转换
        server.serverId = service.uniqueId();
        server.name = service.displayName();
        server.host = service.host;
        server.port = service.port;
        server.gameType = service.gameType();
        server.region = service.region().isEmpty() ? "未知" : service.region();
        server.status = service.healthy ? "online" : "offline";
                 // === 设置玩家数和服务器容量 ===
         int maxPlayers = service.maxPlayers();
         
         // 从元数据获取更准确的最大玩家数
         if (service.metadata.contains("max_players")) {
             maxPlayers = service.metadata["max_players"].toString().toInt();
         } else if (service.metadata.contains("room_capacity")) {
             maxPlayers = service.metadata["room_capacity"].toInt();
         }
         
         // 设置合理的默认值
         server.maxPlayers = maxPlayers > 0 ? maxPlayers : 
                           (service.gameType() == "snake" ? 50 : 100);

         // === 获取当前玩家数 ===
         if (service.metadata.contains("current_players")) {
             server.currentPlayers = service.metadata["current_players"].toInt();
         } else if (service.metadata.contains("active_players")) {
             server.currentPlayers = service.metadata["active_players"].toInt();
         } else if (service.metadata.contains("online_players")) {
             server.currentPlayers = service.metadata["online_players"].toInt();
         } else {
             // 如果没有提供当前玩家数据，使用默认值0
             server.currentPlayers = 0;
         }

         // === 设置网络和性能信息 ===
         if (service.metadata.contains("ping")) {
             server.ping = service.metadata["ping"].toInt();
         } else if (service.metadata.contains("latency")) {
             server.ping = service.metadata["latency"].toInt();
         } else {
             // 如果没有提供延迟数据，使用默认值-1表示未知
             server.ping = -1;
         }

         // 设置负载百分比
         if (service.metadata.contains("load_percentage")) {
             server.loadPercentage = service.metadata["load_percentage"].toDouble();
         } else if (service.metadata.contains("cpu_usage")) {
             server.loadPercentage = service.metadata["cpu_usage"].toDouble() * 100.0;
         } else {
             // 基于当前玩家数计算负载
             double playerRatio = static_cast<double>(server.currentPlayers) / server.maxPlayers;
             server.loadPercentage = playerRatio * 100.0;
         }
        server.version = service.version().isEmpty() ? "未知" : service.version();
        server.lastUpdated = service.lastHeartbeat;
        
        // 从端点列表生成特性
        for (const QString &endpoint : service.endpoints) {
            if (endpoint.contains("rooms")) {
                server.features.append("rooms");
            }
            if (endpoint.contains("leaderboard")) {
                server.features.append("leaderboard");
            }
            if (endpoint.contains("ws")) {
                server.features.append("websocket");
            }
        }
        
        gameServers.append(server);
    }
    
    // 生成汇总信息
    GameService::ServerSummary summary;
    summary.totalServers = services.size();
    summary.onlineServers = 0;
    summary.maintenanceServers = 0;
    summary.totalPlayers = 0;
    summary.totalCapacity = 0;
    
    for (const GameServiceInfo &service : services) {
        if (service.healthy) {
            summary.onlineServers++;
        } else {
            summary.maintenanceServers++;
        }
        
        int maxPlayers = service.maxPlayers();
        if (maxPlayers > 0) {
            summary.totalCapacity += maxPlayers;
        }
    }
    
    // 服务发现API不分页
    summary.currentPage = 1;
    summary.totalPages = 1;
    summary.pageSize = summary.totalServers;
    
    // 更新UI
    updateServerList(gameServers);
    updateServerSummary(summary);
    
    setUIEnabled(true);
    m_progressBar->setVisible(false);
    
    QString statusMessage = QString("🔍 服务发现完成，找到 %1 个服务").arg(services.size());
    updateStatusMessage(statusMessage, "success");
    
    // 存储服务器列表和汇总信息
    m_servers = gameServers;
    m_summary = summary;
}

/**
 * @brief 处理服务发现错误信号
 * @param error 错误信息
 * @param errorCode 错误代码
 *
 * 处理服务发现过程中出现的错误，显示错误信息并恢复UI状态
 */
void GameServerWidget::onServiceDiscoveryError(const QString &error, const QString &errorCode)
{
    qWarning() << "GameServerWidget: Service discovery error:" << errorCode << error;
    
    setUIEnabled(true);
    m_progressBar->setVisible(false);
    
    QString statusMessage = QString("🔍 服务发现失败: %1").arg(error);
    updateStatusMessage(statusMessage, "error");
    
    // 清空服务器列表
    m_serverTable->setRowCount(0);
    m_servers.clear();
    
    // 显示错误详情
    m_serverDetailsText->setHtml(
        QString("<h3>🚨 服务发现错误</h3>"
                "<p><b>错误代码:</b> %1</p>"
                "<p><b>错误信息:</b> %2</p>"
                "<br/>"
                "<p><b>🔧 可能的解决方案:</b></p>"
                "<ul>"
                "<li>🌐 检查网络连接</li>"
                "<li>🔄 尝试切换到传统列表模式</li>"
                "<li>⏱️ 稍后重试</li>"
                "<li>🔍 检查API Gateway状态</li>"
                "</ul>"
                "<br/>"
                "<p><i>如果问题持续存在，请联系系统管理员</i></p>")
                .arg(errorCode.isEmpty() ? "UNKNOWN" : errorCode)
                .arg(error));
    
    // 重置汇总信息
    GameService::ServerSummary emptySummary;
    updateServerSummary(emptySummary);
}
